﻿/**
*┌──────────────────────────────────────────────────────────────┐
*│　描    述：Redis相关的工具类(Redis基础操作帮助类)                                                   
*│　作    者：执笔小白                                              
*│　版    本：2.0                                       
*│　创建时间：2022-5-06 15:40:56                            
*└──────────────────────────────────────────────────────────────┘
*┌──────────────────────────────────────────────────────────────┐
*│　命名空间: Util.NoSQLHelpers                     
*│　类    名：RedisHelper                                     
*└──────────────────────────────────────────────────────────────┘
*/
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Windows.Forms;
using Newtonsoft.Json;
using StackExchange.Redis;

namespace Util.NoSQLHelpers
{
    /// <summary>
    /// Redis基础操作帮助类
    /// </summary>
    public class RedisHelper
    {
        #region 变量
        /// <summary>
        /// 初始化链接
        /// RedisConStr:127.0.0.1:6379,password=ZhibiXiaobai123.
        /// </summary>
        private static ConnectionMultiplexer _con;  //  = ConnectionMultiplexer.Connect("127.0.0.1:6379,password=ZhibiXiaobai123.");//此处写redis的账号和密码;

        // private string _host= ConfigurationSettings.AppSettings["RedisConStr"].Trim();
        #endregion 变量

        #region 初始化
        /// <summary>
        /// 初始化数据库链接
        /// </summary>
        /// <param name="conStr">数据库连接字符串</param>
        public static void Initial(string conStr)
        {
            _con = ConnectionMultiplexer.Connect(conStr);  // 此处写redis的账号和密码
        }
        #endregion 初始化

        #region String类型
        /// <summary>
        /// 查
        /// </summary>
        /// <param name="DataOrder">db的序号</param>
        /// <param name="Key">Key名</param> 
        public static string GetStringValue_Redis(int DataOrder, string Key)
        {
            IDatabase db = _con.GetDatabase(DataOrder);  // GetDatabase()括号中如果不填写数字就默认是0
            return db.StringGet(Key);  // 得到缓存
        }

        /// <summary>
        ///  增
        /// </summary>
        /// <param name="DataOrder">db的序号</param>
        /// <param name="Key">Key名</param>
        /// <param name="Value">Key值</param>
        /// <param name="expiry">过期时间</param>
        /// <returns></returns>
        public static bool AddStringValue_Redis(int DataOrder, string Key, string Value, TimeSpan? expiry = null)
        {
            IDatabase db = _con.GetDatabase(DataOrder);  // GetDatabase()括号中如果不填写数字就默认是0
            if (expiry != null)
            {
                return db.StringSet(Key, Value, expiry);  // string类型存入缓存
            }
            else
            {
                return db.StringSet(Key, Value);  // string类型存入缓存
            }
        }

        /// <summary>
        /// 增加多个值
        /// </summary>
        /// <param name="DataOrder">db的序号</param>
        /// <param name="Key">Key名</param>
        /// <param name="Values">多个Key值</param>
        /// <returns></returns>
        public static bool AddStringValues_Redis(int DataOrder, string Key, List<string> Values)
        {
            IDatabase db = _con.GetDatabase(DataOrder);
            return db.StringSet(new KeyValuePair<RedisKey, RedisValue>[] { new KeyValuePair<RedisKey, RedisValue>(Key, JsonConvert.SerializeObject(Values)) });  // 写入缓存
        }

        // 修改（值）

        /// <summary>
        /// 删
        /// </summary>
        /// <param name="DataOrder">db的序号</param>
        /// <param name="Key">Key名</param>
        /// <returns></returns>
        public static bool DelStringValue_Redis(int DataOrder, string Key)
        {
            IDatabase db = _con.GetDatabase(DataOrder);  // GetDatabase()括号中如果不填写数字就默认是0
            return db.KeyDelete(Key);  // 删除缓存key的缓存
        }
        #endregion String类型

        #region hash 哈希
        /// <summary>
        /// 查
        /// </summary>
        /// <param name="DataOrder">db的序号</param>
        /// <param name="Key">Key</param>
        /// <param name="FieId">HashKey</param>
        /// <returns></returns>
        public static string GetHashValue_Redis(int DataOrder, string Key, string FieId)
        {
            IDatabase database = _con.GetDatabase(DataOrder);
            return database.HashGet(Key, FieId);  // 得到缓存
        }

        /// <summary>
        /// 获取Hash所有的值
        /// </summary>
        /// <param name="DataOrder">db的序号</param>
        /// <param name="Key">Key</param>
        /// <returns></returns>
        public static List<string> GetAllHashValue_Redis(int DataOrder, string Key)
        {
            IDatabase database = _con.GetDatabase(DataOrder);
            HashEntry[] hashEntries = database.HashGetAll(Key);  // 得到缓存

            return hashEntries.Select(x => x.ToString()).ToList();
        }

        /// <summary>
        /// 增
        /// </summary>
        /// <param name="DataOrder">db的序号</param>
        /// <param name="Key">Key</param>
        /// <param name="FieId">HashKey</param>
        /// <param name="Value">HashValue</param>
        /// <returns></returns>
        public static bool AddHashValue_Redis(int DataOrder, string Key, string FieId, string Value)
        {
            IDatabase database = _con.GetDatabase(DataOrder);
            return database.HashSet(Key, FieId, Value);  // 写入缓存
        }

        // 增加多个值
        public static void AddHashValues_Redis(int DataOrder, string Key, Dictionary<string, string> FieIds)
        {
            IDatabase database = _con.GetDatabase(DataOrder);

            HashEntry[] hashEntries = FieIds.Select(i => new HashEntry(i.Key, JsonConvert.SerializeObject(i.Value))).ToArray();

            database.HashSet(Key, hashEntries);
            //foreach (var bb in Listbb)
            //{
            //    database.HashDelete("hashList", bb.Name);//删除缓存key下的缓存
            //}
        }
        // 修改（值）

        /// <summary>
        /// 删除hashkey元素
        /// </summary>
        /// <param name="DataOrder">db的序号</param>
        /// <param name="Key">key</param>
        /// <param name="HashKey">HashKey</param>
        /// <returns></returns>
        public static bool DelHashKeyValue_Redis(int DataOrder, string Key, string HashKey)
        {
            IDatabase database = _con.GetDatabase(DataOrder);
            return database.HashDelete(Key, HashKey);//删除（缓存key和键对应的缓存数据） 
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="DataOrder">db的序号</param>
        /// <param name="Key">key</param>
        /// <param name="Value">Value</param>
        /// <returns></returns>
        public static bool DelHashValue_Redis(int DataOrder, string Key)
        {
            IDatabase database = _con.GetDatabase(DataOrder);
            return database.KeyDelete(Key);//删除（缓存key和键对应的缓存数据） 
        }
        #endregion hash 哈希

        #region set 集合
        /// <summary>
        /// 查所有
        /// </summary>
        /// <param name="DataOrder">db的序号</param>
        /// <param name="Key">Key名</param> 
        public static List<string> GetSetValue_Redis(int DataOrder, string Key)
        {
            IDatabase db = _con.GetDatabase(DataOrder);  // GetDatabase()括号中如果不填写数字就默认是0
            var rrs = db.SetMembers(Key);

            return rrs.Select(x => x.ToString()).ToList();
        }
        /// <summary>
        /// 增
        /// </summary>
        /// <param name="DataOrder">db的序号</param>
        /// <param name="Key">Key</param>
        /// <param name="Value">Value</param>
        /// <returns></returns>
        public static bool AddSetValue_Redis(int DataOrder, string Key, string Value)
        {
            IDatabase db = _con.GetDatabase(DataOrder);  // GetDatabase()括号中如果不填写数字就默认是0
            return db.SetAdd(Key, Value);  // set类型存入缓存
        }
        /// <summary>
        /// 增加多个
        /// </summary>
        /// <param name="DataOrder">db的序号</param>
        /// <param name="Key">Key</param>
        /// <param name="Values">Values</param>
        /// <returns></returns>
        public static long AddSetValues_Redis(int DataOrder, string Key, List<string> Values)
        {
            IDatabase db = _con.GetDatabase(DataOrder);  // GetDatabase()括号中如果不填写数字就默认是0
            return db.SetAdd(Key, Values.Select(i => new StackExchange.Redis.RedisValue(i)).ToArray());
        }
        // 修改（值）


        /// <summary>
        /// 删除SetKey
        /// </summary>
        /// <param name="DataOrder">db的序号</param>
        /// <param name="Key">Key</param>
        /// <param name="FeiId">SetKey</param>
        /// <returns></returns>
        public static bool DelSetKeyValue_Redis(int DataOrder, string Key, string Value)
        {
            IDatabase db = _con.GetDatabase(DataOrder);  // GetDatabase()括号中如果不填写数字就默认是0
            return db.SetRemove(Key, Value);  // 删除（key和value对应的缓存数据）
        }

        /// <summary>
        /// 删
        /// </summary>
        /// <param name="DataOrder">db的序号</param>
        /// <param name="Key">Key</param>
        /// <returns></returns>
        public static bool DelSetValue_Redis(int DataOrder, string Key)
        {
            IDatabase db = _con.GetDatabase(DataOrder);  // GetDatabase()括号中如果不填写数字就默认是0
            return db.KeyDelete(Key);  // 删除key对应的缓存数据
        }

        #endregion set 集合

        #region zset 有序集合
        /// <summary>
        /// 查
        /// </summary>
        /// <param name="DataOrder">db的序号</param>
        /// <param name="Key">Key</param> 
        public static List<ZsetValue> GetZSetValue_Redis(int DataOrder, string Key)
        {
            IDatabase db = _con.GetDatabase(DataOrder);  // GetDatabase()括号中如果不填写数字就默认是0
            var result = db.SortedSetScan(Key);
            return result.Select(item => new ZsetValue() { Value = item.Element, Order = item.Score.ToString() }).ToList<ZsetValue>();
        }

        /// <summary>
        /// 增
        /// </summary>
        /// <param name="DataOrder">db的序号</param>
        /// <param name="Key">Key</param>
        /// <param name="Value">Value</param>
        /// <param name="Order">优先级</param>
        /// <returns></returns>
        public static bool AddZSetValue_Redis(int DataOrder, string Key, string Value, int Order)
        {
            IDatabase db = _con.GetDatabase(DataOrder);  // GetDatabase()括号中如果不填写数字就默认是0
            return db.SortedSetAdd(Key, Value, Order);  //添加
        }
        // 修改（值）

        /// <summary>
        /// 删ZSetKey
        /// </summary>
        /// <param name="DataOrder"></param>
        /// <param name="Key"></param>
        /// <returns></returns>
        public static bool DelZSetKeyValue_Redis(int DataOrder, string Key, string Value)
        {
            IDatabase db = _con.GetDatabase(DataOrder);  // GetDatabase()括号中如果不填写数字就默认是0
            return db.SortedSetRemove(Key, Value);//删除
        }
        // 删
        public static bool DelZSetValue_Redis(int DataOrder, string Key)
        {
            IDatabase db = _con.GetDatabase(DataOrder);  // GetDatabase()括号中如果不填写数字就默认是0
            return db.KeyDelete(Key);//删除key对应的缓存数据
        }

        #endregion zset 有序集合

        #region list 列表
        /// <summary>
        /// 查
        /// </summary>
        /// <param name="DataOrder">db的序号</param>
        /// <param name="Key">Key名</param> 
        public static List<string> GetListValue_Redis(int DataOrder, string Key)
        {
            IDatabase db = _con.GetDatabase(DataOrder);  // GetDatabase()括号中如果不填写数字就默认是0
            var ss = db.ListRange(Key);  // 得到缓存
            return ss.Select(item => item.ToString()).ToList<string>();
        }
        /// <summary>
        /// 增
        /// </summary>
        /// <param name="DataOrder">db的序号</param>
        /// <param name="Key">Key</param>
        /// <param name="Value">Value</param>
        /// <param name="IsTop">是否从顶部</param>
        /// <returns></returns>
        public static long AddListValue_Redis(int DataOrder, string Key, string Value, bool IsTop = false)
        {
            IDatabase db = _con.GetDatabase(DataOrder);  // GetDatabase()括号中如果不填写数字就默认是0
            if (IsTop)
            {
                return db.ListLeftPush(Key, Value);  // 底部插入
            }
            else
            {
                return db.ListRightPush(Key, Value);  // 底部插入
            }
        }

        // 修改（值）

        /// <summary>
        /// 从顶部或者底部删除
        /// </summary>
        /// <param name="DataOrder">db的序号</param>
        /// <param name="Key">Key</param>
        /// <param name="IsTop">是否从顶部</param>
        /// <returns></returns>
        public static string DelListKeyValue_Redis(int DataOrder, string Key, bool IsTop = false)
        {
            IDatabase db = _con.GetDatabase(DataOrder);  // GetDatabase()括号中如果不填写数字就默认是0
            if (IsTop)
            {
                return db.ListLeftPop(Key);  // 底部插入
            }
            else
            {
                return db.ListRightPop(Key);  // 底部插入
            }
        }

        // 删
        public static bool DelListValue_Redis(int DataOrder, string Key)
        {
            IDatabase db = _con.GetDatabase(DataOrder);  // GetDatabase()括号中如果不填写数字就默认是0
            return db.KeyDelete(Key);//删除key对应的缓存数据
        }

        #endregion list 列表

        #region stream 不常用-略

        #endregion  stream
    }

    /// <summary>
    ///  Zset的查询类
    /// </summary>
    public class ZsetValue
    {
        public string Value { set; get; }

        public string Order { set; get; }
    }
}